package com.cbank.platform.weixin;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URISyntaxException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Formatter;
import java.util.HashMap;
import java.util.Map;

import org.apache.commons.lang.StringUtils;
import org.apache.http.client.ClientProtocolException;
import org.apache.log4j.Logger;

import com.alibaba.fastjson.JSONObject;
import com.cbank.utils.HttpClientUtils;
import com.cbank.utils.JSONUtil;
import com.cbank.utils.UniqueKeyGenerator;

/**
 * @author threenoodles
 *
 */
public class WXJSSDKSign {

	public static Logger logger = Logger.getLogger(WXJSSDKSign.class);

	/**
	 * @return
	 * @throws ClientProtocolException
	 * @throws IOException
	 * @throws URISyntaxException
	 */
	public static String fetchToken() {

		try {
			String url = "https://api.weixin.qq.com/cgi-bin/token";
			Map<String, String> params = new HashMap<String, String>(4);
			params.put("grant_type", "client_credential");
			params.put("appid", WeixinPayConfig.APP_ID);
			params.put("secret", WeixinPayConfig.SECRET);
			String content = HttpClientUtils.simpleGetInvoke(url, params);
			JSONObject result = JSONUtil.parseObject(content);
			return (result.containsKey("errcode") || result
					.getIntValue("errcode") != 0) ? StringUtils.EMPTY : result
					.getString("access_token");
		} catch (Exception e) {
			logger.error("fetchToken error:", e);
			return null;
		}
	}

	/**
	 * 获取jsapiticket
	 * 
	 * @return
	 * @throws ClientProtocolException
	 * @throws IOException
	 * @throws URISyntaxException
	 */
	public static String fetchJSApiTicket(String accessToken) {

		try {
			String url = "https://api.weixin.qq.com/cgi-bin/ticket/getticket";
			Map<String, String> params = new HashMap<String, String>(4);
			params.put("access_token", accessToken);
			params.put("type", "jsapi");
			String content = HttpClientUtils.simpleGetInvoke(url, params);
			JSONObject result = JSONUtil.parseObject(content);
			if (result.containsKey("errcode")
					&& result.getIntValue("errcode") != 0) {
				return StringUtils.EMPTY;
			}
			return result.getString("ticket");
		} catch (Exception e) {
			logger.error("fetchJSApiTicket error:", e);
			return StringUtils.EMPTY;
		}
	}

	/**
	 * 根据 jsapi_ticket 签名 url
	 * 
	 * @param jsapi_ticket
	 * @param url
	 * @return
	 */
	public static Map<String, String> sign(String jsapi_ticket, String url) {
		Map<String, String> ret = new HashMap<String, String>();
		String nonce_str = UniqueKeyGenerator.generateToken();
		String timestamp = create_timestamp();
		String string1;
		String signature = "";

		// 注意这里参数名必须全部小写，且必须有序
		string1 = "jsapi_ticket=" + jsapi_ticket + "&noncestr=" + nonce_str
				+ "&timestamp=" + timestamp + "&url=" + url;
		try {
			MessageDigest crypt = MessageDigest.getInstance("SHA-1");
			crypt.reset();
			crypt.update(string1.getBytes("UTF-8"));
			signature = byteToHex(crypt.digest());
		} catch (NoSuchAlgorithmException e) {
			e.printStackTrace();
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		}

		ret.put("url", url);
		ret.put("jsapi_ticket", jsapi_ticket);
		ret.put("nonceStr", nonce_str);
		ret.put("timestamp", timestamp);
		ret.put("signature", signature);

		return ret;
	}

	private static String byteToHex(final byte[] hash) {
		Formatter formatter = new Formatter();
		for (byte b : hash) {
			formatter.format("%02x", b);
		}
		String result = formatter.toString();
		formatter.close();
		return result;
	}

	public static String create_timestamp() {
		return Long.toString(System.currentTimeMillis() / 1000);
	}
}
